package com.seuic.posdsdk.device_interface;

import android.os.Bundle;

import java.util.List;

public interface EmvDevice extends BaseInterface {

    /**
     * Download emv app id list use in EMV transaction
     * @param aids The AID list
     * @return 0 when download success, or other when failed
     */
    int downloadAids(List<String> aids);

    /**
     * Download emv cert list use in EMV transaction
     * @param capks The CAPK list
     * @return 0 when download success, or other when failed
     */
    int downloadCapks(List<String> capks);

    /**
     * Config the on-off status of the card readers
     *
     * @param magcardOn true to on, false to off, default on
     * @param iccardOn true to on, false to off, default on
     * @param rfcardOn true to on, false to off, default on
     * @return config result, 0 to success, other to failed
     */
    int readerConfig(boolean magcardOn, boolean iccardOn, boolean rfcardOn);

    /**
     * Start a process to wait magcard swipe, IC card insert or RF Card present
     *
     * @param readCardCallback The callbacks of read card
     *                          @see EmvDeviceReadCardCallback
     * @param overtime the overtime of waitting, the unit is milliseconds
     */
    void readCard(EmvDeviceReadCardCallback readCardCallback, int overtime);

    /**
     * Power on the icCard already insert or the RFCard already presented
     * Not that you should make sure the card is present, or the method will fail.
     * A way to use this method is call readCard method first, when the card present
     * event is callback, call this function immediately.
     *
     * @return the power on result, 0 to success, other to failed
     */
    int powerOn();

    /**
     * Exchange apdu with IC card or RF card
     * Note that you should call the icCardPowerOn method first before send any APDU.
     *
     * @param cmd the APDU command
     * @return the APDU response
     */
    String exchangeApdu(String cmd);

    /**
     * Power off the IC card or RF card
     * Note that you should call this method after finsh send APDUs
     *
     * @return the power off result, 0 to success, other to failed
     */
    int powerOff();

    /**
     * Start the EMV transaction process
     * When Called, the EMV transaction process will be started
     * The events and result of the process will be returned in callbacks
     * @see TransStartCallback for callback events
     *
     * @param transStartCallback The callbacks in EMV transaction process
     * @param params The input data bundle
     *               @see com.seuic.constants.EmvConstants
     *               AMOUNT(int), the amount of trancaction
     *               TAG_9C(int), the transactions type (tag 9C)
     *               IS_SIMPLE_FLOW(boolean), whether the process is simple flow
     *               TERM_ID(String), the terminal ID (tag 9F1C & 9F1E), the default value is 000000000000000
     *               MERCHANT_NAME(String), the merchant Name (tag 9F4E), the default value is 00000000
     *               MERCHANT_ID(String), the merchant ID ( tag 9F16), the default value is 000000000000000
     *               IS_SUPPORT_ECC(boolean), whether the transaction will support ECash, default false
     *               IS_FORCE_ONLINE(boolean), whether the transaction will be forced online, default false
     *               IS_QPS_SUPPORT(boolean), whether the transaction will support qps function, default false
     *               IS_BIN_A_SUPPORT(boolean), whether the transaction will use BIN A in qps function, default false
     *               IS_BIN_B_SUPPORT(boolean), wehther the transaction will use BIN B in qps function, default false
     *               QPS_LIMIT(int), the amount limit of QPS function, the default is 0
     *               IS_CDCVM_SUPPORT(boolean), whether the CDCVM function will be supported in transaction, default false
     */
    void transStart(TransStartCallback transStartCallback, Bundle params);

    /**
     * Cancel the EMV transaction process already started
     */
    void cancel();

    /**
     * Return the select app result and continue EMV Process
     * In EMV transactions, an application select process should be taken
     * when the card and support multiple apps.
     * After the user finish the process, use this method to
     * return the result and continue EMV Process.
     *
     * @param index The selected application index, -1 to reject app selection
     */
    void selectApp(int index);

    /**
     * Return the confirm cert result continue EMV Process
     * In EMV transactions, a certification confirm process should be taken
     * when CVM process require it.
     * After the user confirm or reject the process, use this method to
     * return the result and continue EMV Process.
     *
     * @param confirmResult The cofirmation result
     *                      CONFIRM_OK to cofirm the card information
     *                      CONFIRM_FAIL to reject
     *                      CONFIRM_BYPASS to bypass
     *                      @see com.seuic.constants.EmvConstants for the constant value
     */
    void confirmCert(String confirmResult);

    /**
     * Return the confirm card information result
     * In EMV transactions, a card info confirmation process should be taken in EMV full flow.
     * After the user confirm or reject the process, use this method to
     * return the result and continue EMV Process.
     *
     * @param confirmResult The confirmation result
     *                      CONFIRM_OK to confirm the card information
     *                      CONFIRM_FAIL to reject
     *                      CONFIRM_BYPASS to bypass
     *                      @see com.seuic.constants.EmvConstants for the constant value
     */
    void confirmCardInfo(String confirmResult);

    /**
     * Tell the EMV process that enter pin is finished
     * In EMV transactions, an enter pin process should be taken
     * when CVM process require it.
     * After pin entered, use this method to
     * return the result and continue EMV Process.
     *
     * @param pin_success Is enter pin process taken successfully
     * @param pin The pin value, just for offline pin, can be any value after online pin process
     */
    void finishEnterPin(boolean pin_success, String pin);

    /**
     * Input online result in EMV transaction
     * In some circumstance, the result of EmvTransStart process is ARQC.
     * Then the app will connect to the server to authenticate the card data and get the server response.
     * Use this method to return the online result to the card, and get the final TC value
     *@see InputOnlineResultCallback for callback events
     *
     * @param inputOnlineResultCallback The result events of input online result process
     * @param params The data form server, the bundle keys defined in EmvConstants
     *             RESPONSE_CODE(String), the respons code of server
     *             ISSUER_FIELD_55(String), the filed 55 data returned form server
     *             @see com.seuic.constants.EmvConstants
     */
    void inputOnlineResult(InputOnlineResultCallback inputOnlineResultCallback, Bundle params);

    /**
     * The read card process callbacks
     */
    interface EmvDeviceReadCardCallback {
        /**
         * The IC card insert event
         */
        void onICCardIn();

        /**
         * The RF card present event
         */
        void onRFCardIn();

        /**
         * The magnetic stripe card swipe event
         *
         * @param data The data of magstripe card
         *             @see com.seuic.constants.EmvConstants
         *             PAN(String), the primary account number
         *             TRACK1(String), the track1 data
         *             TRACK2(String), the track2 data
         *             TRACK3(String), the track3 data
         */
        void onMagcardIn(Bundle data);

        /**
         * The ReadCard Process Failed
         *
         * @param error The error description
         */
        void OnFailed(String error);
    }

    /**
     * The EMV transactions process callbacks
     */
    interface TransStartCallback {

        /**
         * The card detected event
         * Will be called when a IC card Inserted or a RF card present in the field
         *
         * @param type Card type
         *             CARD_TYPE_IC for IC card
         *             CARD_TYPE_ICCL for RF card
         */
        void onCardInsert(String type);

        /**
         * Let the custom to select card app used in transaction
         * After the custom selected, use selectApp Method to input result and continue the EMV process
         * @see EmvDevice.selectApp
         *
         * @param appList The app list both supported by card and terminal
         */
        void onAppSelect(List<String> appList);

        /**
         * Let the custom to confirm certificate information of card
         * After the custom confirmed, use confirmCert Method to input result and continue the EMV process
         * @see EmvDevice.confirmCert
         *
         * @param certType The description of cert type
         * @param certNum The cert number
         */
        void onConfirmCert(String certType, String certNum);

        /**
         * Let the custom to confirm card information
         * After the custom confirmed, use confirmCardInfo Method to input result and continue the EMV process
         * @see EmvDevice.confirmCardInfo
         *
         * @param cardInfoToConfirm data bundle to confirm
         *                          @see com.seuic.constants.EmvConstants
         *                          PAN(String), primary account number of the card
         *                          TRACK2(String), the track2 equivlent data
         *                          PAN_SEQ(String), the PAN sequence
         *                          SERVICE_CODE(String), the service code of card
         *                          CARD_EXP_DATE(String), the expire date of card
         */
        void onConfirmCardInfo(Bundle cardInfoToConfirm);

        /**
         * Let the custom to enter pin
         * After pin entered, use finishEnterPin Method to input result and continue the EMV process
         * @see EmvDevice.finishEnterPin
         *
         * @param is_offline_pin whether the pin required is offline pin
         * @param leftTimes time left for offline pin, not used in oline pin
         */
        void onEnterPin(boolean is_offline_pin, int leftTimes);

        /**
         * The EMV process is complete successfully
         *
         * @param data The process result data bundle
         *             @see com.seuic.constants.EmvConstants
         *             CHANNEL(String), the channel used in transaction
         *                      CHANNEL_MAGCARD, magcard used
         *                      CHANNEL_ICC, IC card used
         *                      CHANNEL_ICCL, RF card used
         *             TRACK1(String), the track1 data, only will present when the channel is magcard and the card support track1
         *             TRACK2(String), the track2 data, only will present when the channel is magcard and the card support track2
         *             TRACK3(String), the track3 data, only will present when the channel is magcard and the card support track3
         *             AC_TYPE(String), the AC type generated by emv cards, only will present when the channel is IC card or RF card
         *                  AC_TYPE_TC, the result is offline approve
         *                  AC_TYPE_ARQC, the result is request online
         *                  AC_TYPE_AAC, the result is offline reject
         *             FEILD_55(String), the field55 TLV datas of emv cards, only will present when the channel is IC card or RF card
         */
        void onSuccess(Bundle data);

        /**
         * The EMV process result in IC card fallback
         */
        void onFallback();

        /**
         * The user used IC card and swiped its magnetic stripe.
         * Stop the current EMV process and tell the user to use ic card instead
         */
        void onUseICCard();

        /**
         * The EMV process failed
         *
         * @param error The error description
         */
        void onFailed(String error);
    }

    /**
     * The EMV input online result callback
     */
    interface InputOnlineResultCallback {
        /**
         * The card authenticate server process finished successfully
         *
         * @param data The result data bundle
         *             @see com.seuic.constants.EmvConstants
         *             AC_TYPE(String), the AC type generated by emv cards
         *                  AC_TYPE_TC, the result is approve
         *                  AC_TYPE_AAC, the result is reject
         *             FEILD_55(String), the field55 TLV datas of emv cards
         *             SCRIPT_RESULT(String), the script execute result, can be null when no script in issuer data
         *
         */
        void onSuccess(Bundle data);

        /**
         * The input online result failed
         *
         * @param error The error description
         */
        void onFailed(String error);
    }
}
